﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.Eval;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;

namespace DoNet.Utils
{
    /// <summary>
    /// NPOI操作Excel类
    /// </summary>
    public static class NpoiUtil
    {
        #region 从datatable中将数据导出到excel
        /// <summary>
        /// 获取创建的Workbook
        /// </summary>
        /// <param name="isXlsx">是否xlsx后缀的Excel</param>
        /// <returns>返回IWorkbook</returns>
        public static IWorkbook GetCreateWorkbook(bool isXlsx = true)
        {
            if (isXlsx)
            {
                return new XSSFWorkbook();
            }
            else
            {
                return new HSSFWorkbook();
            }
        }
        /// <summary>
        /// 获取创建的Sheet
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheetName"></param>
        /// <returns>返回ISheet</returns>
        public static ISheet GetCreateSheet(IWorkbook workbook, string sheetName = null)
        {
            if (!string.IsNullOrWhiteSpace(sheetName))
            {
                return workbook.CreateSheet(sheetName);
            }
            else
            {
                return workbook.CreateSheet();
            }
        }
        /// <summary>
        /// 获取DataTable的列宽
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static int[] GetColumnWidthByDataTable(DataTable dt)
        {
            //取得列宽
            int[] arrColWidth = null;
            if (dt != null && dt.Rows.Count > 0)
            {
                arrColWidth = new int[dt.Columns.Count];
                foreach (DataColumn item in dt.Columns)
                {
                    arrColWidth[item.Ordinal] = Encoding.UTF8.GetBytes(item.ColumnName.ToString()).Length;
                }

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        int intTemp = Encoding.UTF8.GetBytes(dt.Rows[i][j].ToString()).Length;
                        if (intTemp > arrColWidth[j])
                        {
                            arrColWidth[j] = intTemp;
                        }
                    }
                }
            }
            return arrColWidth;
        }
        /// <summary>
        /// DataTable导出到Excel的bytes
        /// Excel2003版本一个工作表最多可有65536行和256列。Excel表格中行的编号从1到65536，列的编号依次用字母A-Z、AA-IV表示。 一个工作簿中最多含有255个工作表，默认情况下是三个工作表.
        /// Excel2007版本一个工作表共有1048576行和16384列。Excel表格中行的编号从1到1048576，列的编号依次用字母A-Z、AA-ZZ、AAA-XFD表示。
        /// </summary>
        /// <param name="dt">源DataTable</param>
        /// <param name="strHeaderText">表头文本</param>
        /// <param name="isXlsx">是否xlsx后缀的Excel</param>
        /// <param name="column_FieldTextWidth">字段</param>
        /// <returns></returns>
        public static byte[] ExportDataTableToExcel(DataTable dt, string strHeaderText, bool isXlsx = true, string[,,] column_FieldTextWidth = null)
        {
            byte[] bytes = null;
            int rowCount = 0;
            int colCount = 0;
            if (isXlsx)
            {
                rowCount = 1048576;
                colCount = 16384;
            }
            else
            {
                rowCount = 65536;
                colCount = 256;
            }

            // 表头 需要一行 
            if (!string.IsNullOrWhiteSpace(strHeaderText))
            {
                rowCount = rowCount - 1;
            }
            // 列头 需要一行
            rowCount = rowCount - 1;

            var recordCount = dt.Rows.Count;
            if (recordCount > 0)
            {
                using (IWorkbook workbook = GetCreateWorkbook(isXlsx))
                {
                    ICellStyle dateStyle = workbook.CreateCellStyle();
                    IDataFormat format = workbook.CreateDataFormat();
                    dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");

                    //表头样式
                    ICellStyle tableHeadStyle = workbook.CreateCellStyle();
                    tableHeadStyle.Alignment = HorizontalAlignment.Center;
                    IFont tableFont = workbook.CreateFont();
                    tableFont.FontHeightInPoints = 20;
                    tableFont.IsBold = true;
                    tableHeadStyle.SetFont(tableFont);

                    //列头样式
                    ICellStyle columnHeadStyle = workbook.CreateCellStyle();
                    columnHeadStyle.Alignment = HorizontalAlignment.Center;
                    IFont columnFont = workbook.CreateFont();
                    columnFont.FontHeightInPoints = 10;
                    columnFont.IsBold = true;
                    columnHeadStyle.SetFont(columnFont);

                    int[] arrColWidth = null;
                    int columnCount = 0; //列数
                    if (column_FieldTextWidth == null)
                    {
                        columnCount = dt.Columns.Count;
                        arrColWidth = GetColumnWidthByDataTable(dt);
                    }
                    else
                    {
                        columnCount = column_FieldTextWidth.GetLength(0);
                    }

                    int totalPage = recordCount % rowCount == 0 ? recordCount / rowCount : recordCount / rowCount + 1;
                    for (var i = 0; i < totalPage; i++)
                    {
                        int rownum = 0;
                        string sheetName = "";
                        if (!string.IsNullOrWhiteSpace(strHeaderText))
                        {
                            sheetName = strHeaderText;
                        }
                        else
                        {
                            if (!string.IsNullOrWhiteSpace(dt.TableName))
                            {
                                sheetName = dt.TableName;
                            }
                            else
                            {
                                sheetName = "Sheet";
                            }
                        }

                        if (i > 0)
                        {
                            sheetName = sheetName + i.ToString();
                        }

                        //创建工作表
                        ISheet sheet = GetCreateSheet(workbook, sheetName);

                        #region 表头及样式
                        if (!string.IsNullOrWhiteSpace(strHeaderText))
                        {
                            IRow headerRow = sheet.CreateRow(rownum);
                            headerRow.HeightInPoints = 25;
                            headerRow.CreateCell(0).SetCellValue(strHeaderText);
                            headerRow.GetCell(0).CellStyle = tableHeadStyle;
                            sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, columnCount - 1));
                            rownum++;
                        }
                        #endregion

                        #region 列头及样式
                        {
                            IRow headerRow = sheet.CreateRow(rownum);

                            if (column_FieldTextWidth != null)
                            {
                                if (columnCount <= colCount)
                                {
                                    for (var m = 0; m < columnCount; m++)
                                    {
                                        headerRow.CreateCell(m).SetCellValue(column_FieldTextWidth[m, 0, 1]);
                                        headerRow.GetCell(m).CellStyle = columnHeadStyle;
                                        /*
                                        ss:Width的值通常是以磅为单位 
                                        10磅等于4个字符。

                                        5磅（5pt）==（5/72）*96 = 6px
                                        1个字符约为7px
                                        */
                                        //设置列宽
                                        sheet.SetColumnWidth(m, ((Convert.ToDouble(column_FieldTextWidth[m, 0, 2]) / 72) * 96) / 7 * 256);
                                    }
                                }
                                else
                                {
                                    //数据列数超过了Excel的列数
                                }
                            }
                            else
                            {
                                if (columnCount <= colCount)
                                {
                                    foreach (DataColumn column in dt.Columns)
                                    {
                                        headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                                        headerRow.GetCell(column.Ordinal).CellStyle = columnHeadStyle;

                                        //设置列宽
                                        if (arrColWidth != null)
                                        {
                                            sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);
                                        }
                                    }
                                }
                                else
                                {
                                    //数据列数超过了Excel的列数
                                }
                            }
                            rownum++;
                        }
                        #endregion


                        #region 填充数据
                        {
                            int startIndex = i * rowCount;
                            int endindex = (i + 1) * rowCount - 1;
                            if (endindex >= recordCount)
                            {
                                endindex = recordCount - 1;
                            }

                            for (int j = startIndex; j <= endindex; j++)//遍历DataTable行
                            {
                                DataRow dataRow = dt.Rows[j];

                                IRow row = sheet.CreateRow(rownum);
                                if (column_FieldTextWidth != null)
                                {
                                    if (columnCount <= colCount)
                                    {
                                        for (int m = 0; m < columnCount; m++)
                                        {
                                            ICell cell = row.CreateCell(m);//在行中添加一列
                                            string columnField = column_FieldTextWidth[m, 0, 0];
                                            foreach (DataColumn column in dt.Columns)
                                            {
                                                if(column.ColumnName == columnField)
                                                {
                                                    string drValue = dataRow[columnField].ToString();
                                                    switch (column.DataType.ToString())
                                                    {
                                                        case "System.String": //字符串类型
                                                            double result;
                                                            if (isNumeric(drValue, out result))
                                                            {
                                                                double.TryParse(drValue, out result);
                                                                cell.SetCellValue(result);
                                                                break;
                                                            }
                                                            else
                                                            {
                                                                cell.SetCellValue(drValue);
                                                                break;
                                                            }
                                                        case "System.DateTime": //日期类型
                                                            {
                                                                DateTime dateV;
                                                                DateTime.TryParse(drValue, out dateV);
                                                                cell.SetCellValue(dateV);
                                                                cell.CellStyle = dateStyle; //格式化显示
                                                            }
                                                            break;
                                                        case "System.Boolean": //布尔型
                                                            bool boolV = false;
                                                            bool.TryParse(drValue, out boolV);
                                                            cell.SetCellValue(boolV);
                                                            break;
                                                        case "System.Int16": //整型
                                                        case "System.Int32":
                                                        case "System.Int64":
                                                        case "System.Byte":
                                                            int intV = 0;
                                                            int.TryParse(drValue, out intV);
                                                            cell.SetCellValue(intV);
                                                            break;
                                                        case "System.Decimal": //浮点型
                                                        case "System.Double":
                                                            double doubV = 0;
                                                            double.TryParse(drValue, out doubV);
                                                            cell.SetCellValue(doubV);
                                                            break;
                                                        case "System.DBNull": //空值处理
                                                            cell.SetCellValue("");
                                                            break;
                                                        default:
                                                            cell.SetCellValue("");
                                                            break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //数据列数超过了Excel的列数
                                    }
                                }
                                else
                                {
                                    if (columnCount <= colCount)
                                    {
                                        foreach (DataColumn column in dt.Columns)
                                        {
                                            ICell cell = row.CreateCell(column.Ordinal);
                                            string drValue = dataRow[column].ToString();
                                            switch (column.DataType.ToString())
                                            {
                                                case "System.String": //字符串类型
                                                    double result;
                                                    if (isNumeric(drValue, out result))
                                                    {
                                                        double.TryParse(drValue, out result);
                                                        cell.SetCellValue(result);
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        cell.SetCellValue(drValue);
                                                        break;
                                                    }

                                                case "System.DateTime": //日期类型
                                                    DateTime dateV;
                                                    DateTime.TryParse(drValue, out dateV);
                                                    cell.SetCellValue(dateV);

                                                    cell.CellStyle = dateStyle; //格式化显示
                                                    break;
                                                case "System.Boolean": //布尔型
                                                    bool boolV = false;
                                                    bool.TryParse(drValue, out boolV);
                                                    cell.SetCellValue(boolV);
                                                    break;
                                                case "System.Int16": //整型
                                                case "System.Int32":
                                                case "System.Int64":
                                                case "System.Byte":
                                                    int intV = 0;
                                                    int.TryParse(drValue, out intV);
                                                    cell.SetCellValue(intV);
                                                    break;
                                                case "System.Decimal": //浮点型
                                                case "System.Double":
                                                    double doubV = 0;
                                                    double.TryParse(drValue, out doubV);
                                                    cell.SetCellValue(doubV);
                                                    break;
                                                case "System.DBNull": //空值处理
                                                    cell.SetCellValue("");
                                                    break;
                                                default:
                                                    cell.SetCellValue("");
                                                    break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //数据列数超过了Excel的列数
                                    }
                                }

                                rownum++;
                            }
                        }
                        #endregion
                    }

                    #region 输出Excel
                    using (MemoryStream stream = new MemoryStream())
                    {
                        workbook.Write(stream);
                        bytes = stream.ToArray();
                    }
                    #endregion
                }
            }
            return bytes;
        }
        #endregion

        #region 从excel中将数据导出到datatable
        /// <summary>
        /// 读取excel 默认第一行为标头
        /// </summary>
        /// <param name="strFileName">excel文档路径</param>
        /// <returns></returns>
        public static DataTable ImportExcelToDataTable(string strFileName)
        {
            DataTable dt = new DataTable();
            IWorkbook wb;
            using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
            {
                wb = WorkbookFactory.Create(file);
            }
            ISheet sheet = wb.GetSheetAt(0);
            dt = ImportDataTable(sheet, 0, true);
            return dt;
        }

        /// <summary>
        /// 读取Excel流到DataTable
        /// </summary>
        /// <param name="stream">Excel流</param>
        /// <returns>第一个sheet中的数据</returns>
        public static DataTable ImportExcelToDataTable(Stream stream)
        {
            try
            {
                DataTable dt = new DataTable();
                IWorkbook wb;
                using (stream)
                {
                    wb = WorkbookFactory.Create(stream);
                }
                ISheet sheet = wb.GetSheetAt(0);
                dt = ImportDataTable(sheet, 0, true);
                return dt;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 读取Excel流到DataTable
        /// </summary>
        /// <param name="stream">Excel流</param>
        /// <param name="sheetName">表单名</param>
        /// <param name="HeaderRowIndex">列头所在行号，-1表示没有列头</param>
        /// <returns>指定sheet中的数据</returns>
        public static DataTable ImportExcelToDataTable(Stream stream, string sheetName, int HeaderRowIndex)
        {
            try
            {
                DataTable dt = new DataTable();
                IWorkbook wb;
                using (stream)
                {
                    wb = WorkbookFactory.Create(stream);
                }
                ISheet sheet = wb.GetSheet(sheetName);
                dt = ImportDataTable(sheet, HeaderRowIndex, true);
                return dt;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 读取Excel流到DataSet
        /// </summary>
        /// <param name="stream">Excel流</param>
        /// <returns>Excel中的数据</returns>
        public static DataSet ImportExcelToDataSet(Stream stream)
        {
            try
            {
                DataSet ds = new DataSet();
                IWorkbook wb;
                using (stream)
                {
                    wb = WorkbookFactory.Create(stream);
                }
                for (int i = 0; i < wb.NumberOfSheets; i++)
                {
                    DataTable dt = new DataTable();
                    ISheet sheet = wb.GetSheetAt(i);
                    dt = ImportDataTable(sheet, 0, true);
                    ds.Tables.Add(dt);
                }
                return ds;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 读取Excel流到DataSet
        /// </summary>
        /// <param name="stream">Excel流</param>
        /// <param name="dict">字典参数，key：sheet名，value：列头所在行号，-1表示没有列头</param>
        /// <returns>Excel中的数据</returns>
        public static DataSet ImportExcelToDataSet(Stream stream, Dictionary<string, int> dict)
        {
            try
            {
                DataSet ds = new DataSet();
                IWorkbook wb;
                using (stream)
                {
                    wb = WorkbookFactory.Create(stream);
                }
                foreach (string key in dict.Keys)
                {
                    DataTable dt = new DataTable();
                    ISheet sheet = wb.GetSheet(key);
                    dt = ImportDataTable(sheet, dict[key], true);
                    ds.Tables.Add(dt);
                }
                return ds;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 读取excel
        /// </summary>
        /// <param name="strFileName">excel文件路径</param>
        /// <param name="sheet">需要导出的sheet</param>
        /// <param name="HeaderRowIndex">列头所在行号，-1表示没有列头</param>
        /// <returns></returns>
        public static DataTable ImportExcelToDataTable(string strFileName, string SheetName, int HeaderRowIndex)
        {
            HSSFWorkbook workbook;
            IWorkbook wb;
            using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
            {
                wb = new HSSFWorkbook(file);
            }
            ISheet sheet = wb.GetSheet(SheetName);
            DataTable table = new DataTable();
            table = ImportDataTable(sheet, HeaderRowIndex, true);
            //ExcelFileStream.Close();
            workbook = null;
            sheet = null;
            return table;
        }

        /// <summary>
        /// 读取excel
        /// </summary>
        /// <param name="strFileName">excel文件路径</param>
        /// <param name="SheetIndex">需要导出的sheet序号</param>
        /// <param name="HeaderRowIndex">列头所在行号，-1表示没有列头</param>
        /// <returns></returns>
        public static DataTable ImportExcelToDataTable(string strFileName, int SheetIndex, int HeaderRowIndex)
        {
            HSSFWorkbook workbook;
            IWorkbook wb;
            using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
            {
                wb = WorkbookFactory.Create(file);
            }
            ISheet isheet = wb.GetSheetAt(SheetIndex);
            DataTable table = new DataTable();
            table = ImportDataTable(isheet, HeaderRowIndex, true);
            //ExcelFileStream.Close();
            workbook = null;
            isheet = null;
            return table;
        }

        /// <summary>
        /// 读取excel
        /// </summary>
        /// <param name="strFileName">excel文件路径</param>
        /// <param name="sheet">需要导出的sheet</param>
        /// <param name="HeaderRowIndex">列头所在行号，-1表示没有列头</param>
        /// <returns></returns>
        public static DataTable ImportExcelToDataTable(string strFileName, string SheetName, int HeaderRowIndex, bool needHeader)
        {
            HSSFWorkbook workbook;
            IWorkbook wb;
            using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
            {
                wb = WorkbookFactory.Create(file);
            }
            ISheet sheet = wb.GetSheet(SheetName);
            DataTable table = new DataTable();
            table = ImportDataTable(sheet, HeaderRowIndex, needHeader);
            //ExcelFileStream.Close();
            workbook = null;
            sheet = null;
            return table;
        }

        /// <summary>
        /// 读取excel
        /// </summary>
        /// <param name="strFileName">excel文件路径</param>
        /// <param name="SheetIndex">需要导出的sheet序号</param>
        /// <param name="HeaderRowIndex">列头所在行号，-1表示没有列头</param>
        /// <returns></returns>
        public static DataTable ImportExcelToDataTable(string strFileName, int SheetIndex, int HeaderRowIndex, bool needHeader)
        {
            HSSFWorkbook workbook;
            IWorkbook wb;
            using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
            {
                wb = WorkbookFactory.Create(file);
            }
            ISheet sheet = wb.GetSheetAt(SheetIndex);
            DataTable table = new DataTable();
            table = ImportDataTable(sheet, HeaderRowIndex, needHeader);
            //ExcelFileStream.Close();
            workbook = null;
            sheet = null;
            return table;
        }

        /// <summary>
        /// 将制定sheet中的数据导出到datatable中
        /// </summary>
        /// <param name="sheet">需要导出的sheet</param>
        /// <param name="HeaderRowIndex">列头所在行号，-1表示没有列头</param>
        /// <returns></returns>
        static DataTable ImportDataTable(ISheet sheet, int HeaderRowIndex, bool needHeader)
        {
            DataTable table = new DataTable();
            IRow headerRow;
            int cellCount;
            try
            {
                if (HeaderRowIndex < 0 || !needHeader)
                {
                    headerRow = sheet.GetRow(0);
                    cellCount = headerRow.LastCellNum;

                    for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
                    {
                        DataColumn column = new DataColumn(Convert.ToString(i));
                        table.Columns.Add(column);
                    }
                }
                else
                {
                    headerRow = sheet.GetRow(HeaderRowIndex);
                    cellCount = headerRow.LastCellNum;

                    for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
                    {
                        if (headerRow.GetCell(i) == null)
                        {
                            if (table.Columns.IndexOf(Convert.ToString(i)) > 0)
                            {
                                DataColumn column = new DataColumn(Convert.ToString("重复列名" + i));
                                table.Columns.Add(column);
                            }
                            else
                            {
                                DataColumn column = new DataColumn(Convert.ToString(i));
                                table.Columns.Add(column);
                            }

                        }
                        else if (table.Columns.IndexOf(headerRow.GetCell(i).ToString()) > 0)
                        {
                            DataColumn column = new DataColumn(Convert.ToString("重复列名" + i));
                            table.Columns.Add(column);
                        }
                        else
                        {
                            DataColumn column = new DataColumn(headerRow.GetCell(i).ToString());
                            table.Columns.Add(column);
                        }
                    }
                }
                int rowCount = sheet.LastRowNum;
                for (int i = (HeaderRowIndex + 1); i <= sheet.LastRowNum; i++)
                {
                    try
                    {
                        IRow row;
                        if (sheet.GetRow(i) == null)
                        {
                            row = sheet.CreateRow(i);
                        }
                        else
                        {
                            row = sheet.GetRow(i);
                        }

                        DataRow dataRow = table.NewRow();

                        for (int j = row.FirstCellNum; j <= cellCount; j++)
                        {
                            try
                            {
                                if (row.GetCell(j) != null)
                                {
                                    switch (row.GetCell(j).CellType)
                                    {
                                        case CellType.String:
                                            string str = row.GetCell(j).StringCellValue;
                                            if (str != null && str.Length > 0)
                                            {
                                                dataRow[j] = str.ToString();
                                            }
                                            else
                                            {
                                                dataRow[j] = null;
                                            }
                                            break;
                                        case CellType.Numeric:
                                            if (DateUtil.IsCellDateFormatted(row.GetCell(j)))
                                            {
                                                dataRow[j] = DateTime.FromOADate(row.GetCell(j).NumericCellValue);
                                            }
                                            else
                                            {
                                                dataRow[j] = Convert.ToDouble(row.GetCell(j).NumericCellValue);
                                            }
                                            break;
                                        case CellType.Boolean:
                                            dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
                                            break;
                                        case CellType.Error:
                                            dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
                                            break;
                                        case CellType.Formula:
                                            switch (row.GetCell(j).CachedFormulaResultType)
                                            {
                                                case CellType.String:
                                                    string strFORMULA = row.GetCell(j).StringCellValue;
                                                    if (strFORMULA != null && strFORMULA.Length > 0)
                                                    {
                                                        dataRow[j] = strFORMULA.ToString();
                                                    }
                                                    else
                                                    {
                                                        dataRow[j] = null;
                                                    }
                                                    break;
                                                case CellType.Numeric:
                                                    dataRow[j] = Convert.ToString(row.GetCell(j).NumericCellValue);
                                                    break;
                                                case CellType.Boolean:
                                                    dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
                                                    break;
                                                case CellType.Error:
                                                    dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
                                                    break;
                                                default:
                                                    dataRow[j] = "";
                                                    break;
                                            }
                                            break;
                                        default:
                                            dataRow[j] = "";
                                            break;
                                    }
                                }
                            }
                            catch (Exception exception)
                            {
                                //wl.WriteLogs(exception.ToString());
                            }
                        }
                        table.Rows.Add(dataRow);
                    }
                    catch (Exception exception)
                    {
                        //wl.WriteLogs(exception.ToString());
                    }
                }
            }
            catch (Exception exception)
            {
                //wl.WriteLogs(exception.ToString());
            }
            return table;
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="outputFile"></param>
        /// <param name="sheetname"></param>
        /// <param name="dt"></param>
        public static void InsertSheet(string outputFile, string sheetname, DataTable dt)
        {
            using (FileStream readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
            {
                using (IWorkbook hssfworkbook = WorkbookFactory.Create(readfile))
                {
                    //HSSFWorkbook hssfworkbook = new HSSFWorkbook(readfile);
                    int num = hssfworkbook.GetSheetIndex(sheetname);
                    ISheet sheet1;
                    if (num >= 0)
                    {
                        sheet1 = hssfworkbook.GetSheet(sheetname);
                    }
                    else
                    {
                        sheet1 = hssfworkbook.CreateSheet(sheetname);
                    }

                    if (sheet1.GetRow(0) == null)
                    {
                        sheet1.CreateRow(0);
                    }
                    for (int coluid = 0; coluid < dt.Columns.Count; coluid++)
                    {
                        if (sheet1.GetRow(0).GetCell(coluid) == null)
                        {
                            sheet1.GetRow(0).CreateCell(coluid);
                        }

                        sheet1.GetRow(0).GetCell(coluid).SetCellValue(dt.Columns[coluid].ColumnName);
                    }

                    for (int i = 1; i <= dt.Rows.Count; i++)
                    {
                        if (sheet1.GetRow(i) == null)
                        {
                            sheet1.CreateRow(i);
                        }
                        for (int coluid = 0; coluid < dt.Columns.Count; coluid++)
                        {
                            if (sheet1.GetRow(i).GetCell(coluid) == null)
                            {
                                sheet1.GetRow(i).CreateCell(coluid);
                            }

                            sheet1.GetRow(i).GetCell(coluid).SetCellValue(dt.Rows[i - 1][coluid].ToString());
                        }
                    }
                    using (FileStream writefile = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write))
                    {
                        hssfworkbook.Write(writefile);
                    }
                }
            }
        }

        #region 更新excel中的数据
        /// <summary>
        /// 更新Excel表格
        /// </summary>
        /// <param name="outputFile">需更新的excel表格路径</param>
        /// <param name="sheetname">sheet名</param>
        /// <param name="updateData">需更新的数据</param>
        /// <param name="coluid">需更新的列号</param>
        /// <param name="rowid">需更新的开始行号</param>
        public static void UpdateExcel(string outputFile, string sheetname, string[] updateData, int coluid, int rowid)
        {
            using(FileStream readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
            {
                //using (IWorkbook hssfworkbook = WorkbookFactory.Create(readfile))
                using (HSSFWorkbook hssfworkbook = new HSSFWorkbook(readfile))
                {
                    ISheet sheet1 = hssfworkbook.GetSheet(sheetname);
                    for (int i = 0; i < updateData.Length; i++)
                    {
                        if (sheet1.GetRow(i + rowid) == null)
                        {
                            sheet1.CreateRow(i + rowid);
                        }
                        if (sheet1.GetRow(i + rowid).GetCell(coluid) == null)
                        {
                            sheet1.GetRow(i + rowid).CreateCell(coluid);
                        }

                        sheet1.GetRow(i + rowid).GetCell(coluid).SetCellValue(updateData[i]);
                    }
                    using (FileStream writefile = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write))
                    {
                        hssfworkbook.Write(writefile);
                    }
                }
            }
        }

        /// <summary>
        /// 更新Excel表格
        /// </summary>
        /// <param name="outputFile">需更新的excel表格路径</param>
        /// <param name="sheetname">sheet名</param>
        /// <param name="updateData">需更新的数据</param>
        /// <param name="coluids">需更新的列号</param>
        /// <param name="rowid">需更新的开始行号</param>
        public static void UpdateExcel(string outputFile, string sheetname, string[][] updateData, int[] coluids, int rowid)
        {
            using (FileStream readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
            {
                using (HSSFWorkbook hssfworkbook = new HSSFWorkbook(readfile))
                {
                    ISheet sheet1 = hssfworkbook.GetSheet(sheetname);
                    for (int j = 0; j < coluids.Length; j++)
                    {
                        for (int i = 0; i < updateData[j].Length; i++)
                        {
                            if (sheet1.GetRow(i + rowid) == null)
                            {
                                sheet1.CreateRow(i + rowid);
                            }
                            if (sheet1.GetRow(i + rowid).GetCell(coluids[j]) == null)
                            {
                                sheet1.GetRow(i + rowid).CreateCell(coluids[j]);
                            }
                            sheet1.GetRow(i + rowid).GetCell(coluids[j]).SetCellValue(updateData[j][i]);
                        }
                    }

                    using (FileStream writefile = new FileStream(outputFile, FileMode.Create))
                    {
                        hssfworkbook.Write(writefile);
                    }
                }
            }
        }

        /// <summary>
        /// 更新Excel表格
        /// </summary>
        /// <param name="outputFile">需更新的excel表格路径</param>
        /// <param name="sheetname">sheet名</param>
        /// <param name="updateData">需更新的数据</param>
        /// <param name="coluid">需更新的列号</param>
        /// <param name="rowid">需更新的开始行号</param>
        public static void UpdateExcel(string outputFile, string sheetname, double[] updateData, int coluid, int rowid)
        {
            using (FileStream readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
            {
                using (HSSFWorkbook hssfworkbook = new HSSFWorkbook(readfile))
                {
                    ISheet sheet1 = hssfworkbook.GetSheet(sheetname);
                    for (int i = 0; i < updateData.Length; i++)
                    {
                        if (sheet1.GetRow(i + rowid) == null)
                        {
                            sheet1.CreateRow(i + rowid);
                        }
                        if (sheet1.GetRow(i + rowid).GetCell(coluid) == null)
                        {
                            sheet1.GetRow(i + rowid).CreateCell(coluid);
                        }

                        sheet1.GetRow(i + rowid).GetCell(coluid).SetCellValue(updateData[i]);
                    }
                    using (FileStream writefile = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
                    {
                        hssfworkbook.Write(writefile);
                    }
                }
            }
        }

        /// <summary>
        /// 更新Excel表格
        /// </summary>
        /// <param name="outputFile">需更新的excel表格路径</param>
        /// <param name="sheetname">sheet名</param>
        /// <param name="updateData">需更新的数据</param>
        /// <param name="coluids">需更新的列号</param>
        /// <param name="rowid">需更新的开始行号</param>
        public static void UpdateExcel(string outputFile, string sheetname, double[][] updateData, int[] coluids, int rowid)
        {
            using (FileStream readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
            {
                using (HSSFWorkbook hssfworkbook = new HSSFWorkbook(readfile))
                {
                    ISheet sheet1 = hssfworkbook.GetSheet(sheetname);
                    for (int j = 0; j < coluids.Length; j++)
                    {
                        for (int i = 0; i < updateData[j].Length; i++)
                        {
                            if (sheet1.GetRow(i + rowid) == null)
                            {
                                sheet1.CreateRow(i + rowid);
                            }
                            if (sheet1.GetRow(i + rowid).GetCell(coluids[j]) == null)
                            {
                                sheet1.GetRow(i + rowid).CreateCell(coluids[j]);
                            }
                            sheet1.GetRow(i + rowid).GetCell(coluids[j]).SetCellValue(updateData[j][i]);
                        }
                    }
                    using (FileStream writefile = new FileStream(outputFile, FileMode.Create))
                    {
                        hssfworkbook.Write(writefile);
                    }
                }
            }
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="outputFile"></param>
        /// <returns></returns>
        public static int GetSheetNumber(string outputFile)
        {
            int number = 0;
            using (FileStream readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
            {
                using (HSSFWorkbook hssfworkbook = new HSSFWorkbook(readfile))
                {
                    number = hssfworkbook.NumberOfSheets;
                }
            }
            return number;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="outputFile"></param>
        /// <returns></returns>
        public static ArrayList GetSheetName(string outputFile)
        {
            ArrayList arrayList = new ArrayList();
            using (FileStream readfile = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
            {
                using (HSSFWorkbook hssfworkbook = new HSSFWorkbook(readfile))
                {
                    for (int i = 0; i < hssfworkbook.NumberOfSheets; i++)
                    {
                        arrayList.Add(hssfworkbook.GetSheetName(i));
                    }
                }
            }
            return arrayList;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool isNumeric(String message, out double result)
        {
            Regex rex = new Regex(@"^[-]?\d+[.]?\d*$");
            result = -1;
            if (rex.IsMatch(message))
            {
                result = double.Parse(message);
                return true;
            }
            else
            {
                return false;
            }
        }



        //////////  现用导出  \\\\\\\\\\  
        /// <summary>
        /// 用于Web导出                                                                                             第一步
        /// </summary>
        /// <param name="dt">源DataTable</param>
        /// <param name="strHeaderText">表头文本</param>
        /// <param name="strFileName">文件名</param>
        //public static void ExportByWeb(DataTable dt, string strHeaderText, string strFileName)
        //{
        //    HttpContext curContext = HttpContext.Current;

        //    // 设置编码和附件格式
        //    curContext.Response.ContentType = "application/vnd.ms-excel";
        //    curContext.Response.ContentEncoding = Encoding.UTF8;
        //    curContext.Response.Charset = "";
        //    curContext.Response.AppendHeader("Content-Disposition",
        //    "attachment;filename=" + HttpUtility.UrlEncode(strFileName, Encoding.UTF8));

        //    curContext.Response.BinaryWrite(Export(dt, strHeaderText).GetBuffer());
        //    curContext.Response.End();
        //}

        /// <summary>
        /// DataTable导出到Excel的MemoryStream                                                                      第二步
        /// </summary>
        /// <param name="dt">源DataTable</param>
        /// <param name="strHeaderText">表头文本</param>
        public static MemoryStream Export(DataTable dt, string strHeaderText)
        {
            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.CreateSheet() as HSSFSheet;

            #region 右击文件 属性信息
            {
                DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                dsi.Company = "NPOI";
                workbook.DocumentSummaryInformation = dsi;

                SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                si.Author = "文件作者信息"; //填加xls文件作者信息
                si.ApplicationName = "创建程序信息"; //填加xls文件创建程序信息
                si.LastAuthor = "最后保存者信息"; //填加xls文件最后保存者信息
                si.Comments = "作者信息"; //填加xls文件作者信息
                si.Title = "标题信息"; //填加xls文件标题信息
                si.Subject = "主题信息";//填加文件主题信息

                si.CreateDateTime = DateTime.Now;
                workbook.SummaryInformation = si;
            }
            #endregion

            HSSFCellStyle dateStyle = workbook.CreateCellStyle() as HSSFCellStyle;
            HSSFDataFormat format = workbook.CreateDataFormat() as HSSFDataFormat;
            dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");

            //取得列宽
            int[] arrColWidth = new int[dt.Columns.Count];
            foreach (DataColumn item in dt.Columns)
            {
                arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
            }
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length;
                    if (intTemp > arrColWidth[j])
                    {
                        arrColWidth[j] = intTemp;
                    }
                }
            }
            int rowIndex = 0;
            foreach (DataRow row in dt.Rows)
            {
                #region 新建表，填充表头，填充列头，样式
                if (rowIndex == 65535 || rowIndex == 0)
                {
                    if (rowIndex != 0)
                    {
                        sheet = workbook.CreateSheet() as HSSFSheet;
                    }

                    #region 表头及样式
                    {
                        if (string.IsNullOrEmpty(strHeaderText))
                        {
                            HSSFRow headerRow = sheet.CreateRow(0) as HSSFRow;
                            headerRow.HeightInPoints = 25;
                            headerRow.CreateCell(0).SetCellValue(strHeaderText);
                            HSSFCellStyle headStyle = workbook.CreateCellStyle() as HSSFCellStyle;
                            //headStyle.Alignment = CellHorizontalAlignment.CENTER;
                            HSSFFont font = workbook.CreateFont() as HSSFFont;
                            font.FontHeightInPoints = 20;
                            font.IsBold = true;
                            //font.Boldweight = 700;
                            headStyle.SetFont(font);
                            headerRow.GetCell(0).CellStyle = headStyle;
                            sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));
                            //headerRow.Dispose();
                        }
                    }
                    #endregion

                    #region 列头及样式
                    {
                        HSSFRow headerRow = sheet.CreateRow(0) as HSSFRow;
                        HSSFCellStyle headStyle = workbook.CreateCellStyle() as HSSFCellStyle;
                        //headStyle.Alignment = CellHorizontalAlignment.CENTER;
                        HSSFFont font = workbook.CreateFont() as HSSFFont;
                        font.FontHeightInPoints = 10;
                        font.IsBold = true;
                        //font.Boldweight = 700;
                        headStyle.SetFont(font);
                        foreach (DataColumn column in dt.Columns)
                        {
                            headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                            headerRow.GetCell(column.Ordinal).CellStyle = headStyle;

                            //设置列宽
                            sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);
                        }
                        //headerRow.Dispose();
                    }
                    #endregion

                    rowIndex = 1;
                }
                #endregion


                #region 填充内容
                HSSFRow dataRow = sheet.CreateRow(rowIndex) as HSSFRow;
                foreach (DataColumn column in dt.Columns)
                {
                    HSSFCell newCell = dataRow.CreateCell(column.Ordinal) as HSSFCell;

                    string drValue = row[column].ToString();

                    switch (column.DataType.ToString())
                    {
                        case "System.String"://字符串类型
                            newCell.SetCellValue(drValue);
                            break;
                        case "System.DateTime"://日期类型
                            DateTime dateV;
                            DateTime.TryParse(drValue, out dateV);
                            newCell.SetCellValue(dateV);

                            newCell.CellStyle = dateStyle;//格式化显示
                            break;
                        case "System.Boolean"://布尔型
                            bool boolV = false;
                            bool.TryParse(drValue, out boolV);
                            newCell.SetCellValue(boolV);
                            break;
                        case "System.Int16"://整型
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            int intV = 0;
                            int.TryParse(drValue, out intV);
                            newCell.SetCellValue(intV);
                            break;
                        case "System.Decimal"://浮点型
                        case "System.Double":
                            double doubV = 0;
                            double.TryParse(drValue, out doubV);
                            newCell.SetCellValue(doubV);
                            break;
                        case "System.DBNull"://空值处理
                            newCell.SetCellValue("");
                            break;
                        default:
                            newCell.SetCellValue("");
                            break;
                    }
                }
                #endregion

                rowIndex++;
            }
            using (MemoryStream ms = new MemoryStream())
            {
                workbook.Write(ms);
                ms.Flush();
                ms.Position = 0;

                //sheet.Dispose();
                //workbook.Dispose();//一般只用写这一个就OK了，他会遍历并释放所有资源，但当前版本有问题所以只释放sheet
                return ms;
            }
        }

        /// <summary>
        /// 由DataSet导出Excel
        /// </summary>
        /// <param name="sourceTable">要导出数据的DataTable</param>
        /// <param name="sheetName">工作表名称</param>
        /// <returns>Excel工作表</returns>
        private static MemoryStream ExportDataSetToExcel(DataSet sourceDs, string sheetName)
        {
            HSSFWorkbook workbook = new HSSFWorkbook();
            MemoryStream ms = new MemoryStream();
            string[] sheetNames = sheetName.Split(',');
            for (int i = 0; i < sheetNames.Length; i++)
            {
                ISheet sheet = workbook.CreateSheet(sheetNames[i]);

                #region 列头
                IRow headerRow = sheet.CreateRow(0);
                HSSFCellStyle headStyle = workbook.CreateCellStyle() as HSSFCellStyle;
                HSSFFont font = workbook.CreateFont() as HSSFFont;
                font.FontHeightInPoints = 10;
                font.IsBold = true;
                //font.Boldweight = 700;
                headStyle.SetFont(font);

                //取得列宽
                int[] arrColWidth = new int[sourceDs.Tables[i].Columns.Count];
                foreach (DataColumn item in sourceDs.Tables[i].Columns)
                {
                    arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
                }

                // 处理列头
                foreach (DataColumn column in sourceDs.Tables[i].Columns)
                {
                    headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                    headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
                    //设置列宽
                    sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);

                }
                #endregion

                #region 填充值
                int rowIndex = 1;
                foreach (DataRow row in sourceDs.Tables[i].Rows)
                {
                    IRow dataRow = sheet.CreateRow(rowIndex);
                    foreach (DataColumn column in sourceDs.Tables[i].Columns)
                    {
                        dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
                    }
                    rowIndex++;
                }
                #endregion
            }
            workbook.Write(ms);
            ms.Flush();
            ms.Position = 0;
            workbook = null;
            return ms;
        }

        /// <summary>
        /// 验证导入的Excel是否有数据
        /// </summary>
        /// <param name="excelFileStream"></param>
        /// <returns></returns>
        public static bool HasData(Stream excelFileStream)
        {
            using (excelFileStream)
            {
                IWorkbook workBook = new HSSFWorkbook(excelFileStream);
                if (workBook.NumberOfSheets > 0)
                {
                    ISheet sheet = workBook.GetSheetAt(0);
                    return sheet.PhysicalNumberOfRows > 0;
                }
            }
            return false;
        }
    }
}
